package com.nlscan.ncomgateway.core.data.repository

import androidx.lifecycle.LiveData
import androidx.lifecycle.map
import com.nlscan.ncomgateway.core.database.dao.DeviceDao
import com.nlscan.ncomgateway.core.database.model.DeviceEntity
import com.nlscan.ncomgateway.core.database.model.asEntity
import com.nlscan.ncomgateway.core.database.model.asExternalModel
import com.nlscan.ncomgateway.core.model.entity.Device
import com.nlscan.ncomgateway.core.remote.DeviceRemoteDataSource

/**
 * <pre>
 *  author: lin.qing
 *  time  : 2023/3/21
 *  desc  :
 * </pre>
 * 2023-03-21 暂不使用Dagger，当前放到 App中，（不符合模块化），是否考虑单例？
 */
class DeviceRepository constructor(
    private val deviceDao: DeviceDao,
    private val deviceRemote: DeviceRemoteDataSource
) : IDeviceRepository {

    fun addDevice(device: Device) {
        val deviceEntity = device.asEntity()
        val list = mutableListOf<DeviceEntity>(deviceEntity)
        deviceDao.insertDevices(list)
    }

    fun getDevices(): LiveData<List<Device>> {
        //先向remote设备获取
        deviceRemote.getDevices()
            .map {
                it?.let {
                    deviceDao.getDeviceEntity(it.address)?.run {
                        if (connectionState != it.connectionState
                            || bondState != it.bondState
                        ) {
                            connectionState = it.connectionState
                            bondState = it.bondState

                            //todo 待优化
                            //临时方案适配，避免蓝牙未打开情况下，设备名称为空，则不做更新，避免设备名称被清空
                            if (it.deviceName.isNotEmpty()) {
                                deviceName = it.deviceName
                            }
                            //更新别名
                            if ((it.alias?.isNotEmpty()) == true) {
                                alias = it.alias
                            }
                            deviceDao.updateDevices(arrayListOf(this))
                        }
                    }
                }
            }
        //再获取本地db值
        return deviceDao.getDeviceEntities()
            .map {
                it.map(DeviceEntity::asExternalModel)
            }
    }

    fun getDevice(address: String): Device? = deviceDao.getDeviceEntity(address)?.asExternalModel()

    fun getDeviceAddressesFromDb(): List<String>? =
        deviceDao.getDeviceEntities().value?.map {
            it.address
        }

    fun updateDevice(device: Device) = device.asEntity().let {
        deviceDao.updateDevices(arrayListOf(it))
    }

//    fun updateDevices(list:List<Device>) {
//        list.map {
//            it.asEntity()
//        }
//        deviceDao.updateDevices(list)
//    }


    fun deleteDevice(address: String) {
        //删除前清除工作，停止连接
        deviceRemote.deleteDevice(address)
        deviceDao.deleteDevices(mutableListOf(address))
    }

    fun getConnection(address: String) =
        deviceRemote.getConnection(address)


    fun setAlias(device: Device, newName: String) {
        // TODO: 待优化
        deviceRemote.setAlias(device, newName)
        device.alias = newName
        updateDevice(device)
    }

    fun getDeviceList() : List<Device>{
        val list = deviceDao.getDeviceEntityList().map {
            it.asExternalModel()
        }
        return list
    }

}